/****************************************************************************
 *       Copyright (c) 2025 Qualcomm Technologies International, Ltd
****************************************************************************/

#ifndef _LEA_HDR_SDU_PARSER_IF_H_
#define _LEA_HDR_SDU_PARSER_IF_H_

/*****************************************************************************
Include Files
*/
#include "capabilities.h"

/*
 *                       SDU representaion
 * +--------------------------------------------------------+
 * |                         SDU1                           |
 * |      Blk 1       |      Blk 2      ...     Blk N       |
 * +------------------+------------------+------------------+
 * |   Frame 0 to N   |   Frame 0 to N   |   Frame 0 to N   |
 * |         Or       |         Or       |         Or       |
 * | Ch 0, Ch1, ..ChN | Ch 0, Ch1, ..ChN | Ch 0, Ch1, ..ChN |
 * +------------------+------------------+------------------+
 */


/****************************************************************************
Type & Constant Definitions
*/

typedef enum
{
    METADATA_STATUS_OK = 0,
    METADATA_STATUS_CRC_ERROR = 1,
    METADATA_STATUS_NOTHING_RECEIVED = 2,
    /* this corresponds to the scos_time_missed debug variable in the BlueCore firmware. */
    METADATA_STATUS_NEVER_SCHEDULED = 3,
    METADATA_STATUS_OK_WBM = 4,
    /* Although this is an "internal" status value
     * (it doesn't come from the BTSS) it's passed to
     * the decoder in case it does anything special with
     * zero-length SDU */
    METADATA_STATUS_ZERO_PACKET = 0xFE,
    METADATA_STATUS_NO_PACKET = 0xFF
} SCO_ISO_METADATA_STATUS;

typedef enum
{
    /* Decode this frame */
    STATUS_GOOD = 0,
    /* Invoke PLC to generate fake PCM block */
    STATUS_CRC_ERR = 1,
    /* Invoke PLC to generate fake PCM block */
    STATUS_SDU_LOST = 2,
    /* Generate silance PCM block */
    STATUS_ZERO_LEN_SDU = 3,
    /* Fake SDU received from interface, generate fake PCM/silance block
     * This can happen if BT failed to send any data */
    STATUS_SDU_NOTHING_RECEIVED = 4,
    /* Unknown status, def value or value if SDU parser failed to extract data
     * Generate fake PCM block to avoid audio stall */
    STATUS_SDU_UNKNOWN = 0xff,
} LEA_HDR_SDU_PARSER_RCV_STATUS;

/* Parsed SDU Statistics */
typedef struct lea_hdr_sdu_parser_stats_t
{
    unsigned legacy_sdu_count;

    unsigned hdr_v1_chunk_count;
    unsigned hdr_v2_chunk_count;
    unsigned hdr_wbm_chunk_count;
    unsigned hdr_ft_chunk_count;
    unsigned hdr_iso_param_chunk_count;
    unsigned hdr_unknown_chunk_count;
} LEA_HDR_SDU_PARSER_STATS;

/* LEA HDR SDU parser's main structure */
typedef struct lea_hdr_sdu_parser_data_t
{
    /* Parsed encoded frame Cbuffer pointer
     * Length of Cbuffer should be enough to hold at least 2 max size SDU */
    tCbuffer *parsed_sdu_buf_ptr;

    /* Number of SDU parsed */
    unsigned num_sdu_parsed;

    /* Received SDU's Status
     * It should be read only when "num_sdu_parsed" has non zero value
     * As of now, we can receive at max 2 blobs in one go
     * data_blob_status[00:07] SDU 1 status (LEA_HDR_SDU_PARSER_RCV_STATUS)
     * data_blob_status[08:15] SDU 2 status (LEA_HDR_SDU_PARSER_RCV_STATUS)
     */
    unsigned data_sdu_status;

    /* [00:15] SDU 1 length
     * [16:31] SDU 2 length, if available
     */
    uint32_t parsed_sdu_len_bytes;

    /* Statistics counter for all types of header received.
     * Make sure the elements are zero during struct object creation
     */
    LEA_HDR_SDU_PARSER_STATS hdr_sdu_statistics;

    /* Need a CBuffer to parse the HDR data (Internally created) */
    tCbuffer *scratch_buffer_ptr;

    /* Operator ID stored for logging */
    unsigned op_id;

    /* Qualcomm Decoder private pasrsed data */
    void *pvt_data_ptr;
} LEA_HDR_SDU_PARSER_DATA;


/***************************************************************************
Public Function Declarations
*/

/**
 * \brief Allocate memory for header data parser.
 *
 * \param decoder_hdr_sdu_parser_data_ptr   Pointer to HDR parser instance.
 * \param parsed_sdu_buf_size_words         Size of parsed_sdu_buf in words.
 * \param                     op_id         Operator's ID to enhance log
 */
extern bool lea_hdr_sdu_parser_allocate_memory(LEA_HDR_SDU_PARSER_DATA *decoder_hdr_sdu_parser_data_ptr, \
                                               unsigned parsed_sdu_buf_size_words, unsigned op_id);

/**
 * \brief Deallocate memory for header data parser.
 *
 * \param decoder_hdr_sdu_parser_data_ptr   Pointer to HDR parser instance.
 */
extern void lea_hdr_sdu_parser_deallocate_memory(LEA_HDR_SDU_PARSER_DATA *decoder_hdr_sdu_parser_data_ptr);

/**
 * \brief Parse HDR frame received over the LEA interface and copy the encoded data into an intermediate circular buffer.
 *
 * This function processes HDR frames received via the LEA interface. The received data, along with 
 * its frame status, is copied into an intermediate buffer for further processing by the decoder.
 *
 * \param           *terminal_input_buffer_ptr   Pointer to the source circular buffer used for reading data.
 * \param                   payload_len_octets   Number of bytes to be read from the source buffer.
 * \param                 sco_iso_frame_status   Metadata status of the SCO ISO frame as specified by the input interface.
 * \param     *decoder_hdr_sdu_parser_data_ptr   Pointer to the HDR parser instance, which provides the parsed result for the decoder.
 */
extern void lea_hdr_sdu_parser_parse_data(tCbuffer *terminal_input_buffer_ptr, unsigned payload_len_octets, \
                                          SCO_ISO_METADATA_STATUS sco_iso_frame_status, LEA_HDR_SDU_PARSER_DATA *decoder_hdr_sdu_parser_data_ptr);

#endif /* _LEA_HDR_SDU_PARSER_IF_H_ */